<template>
  <el-button
    type="primary"
    :loading="loading"
    icon="el-icon-printer"
    size="mini"
    @click="handleClick"
    >打印<iframe style="display: none" ref="iframe"></iframe
  ></el-button>
</template>

<script>
import {
  getPageHeight,
  getPageWidth,
  pageNumText,
} from "../../views/printTemplate/config/util";
import componentList from "../../views/printTemplate/config/component";
export default {
  name: "l-print-btn",
  props: {
    code: String,
    schema: Object,
    getFormData: Function,
    isPreview: Boolean,
  },
  data() {
    return {
      loading: false,
      pageSchema: null,
      schemaCode:'',
      timeNum: 1200,
      
    };
  },
  computed: {
    myComponentList() {
      const res = {};
      for (let item of componentList) {
        res[item.type] = item;
      }
      return res;
    },
    myPageSchema() {
      if (this.code) {
        return this.pageSchema;
      } else {
        const schema = this.$deepClone(this.schema);
        for (let page of schema.pages) {
          const components = [];
          for (let component of page.components) {
            components.push(component.config || component);
          }
          page.components = components;
        }

        return schema;
      }
    },
    pageConfig() {
      return this.myPageSchema.pageConfig;
    },
    pageHeightPt() {
      return this.$mmToPt(this.pageHeight);
    },
    pageHeight() {
      if (this.pageConfig.direction == "1") {
        return this._pageHeight;
      } else {
        return this._pageWidth;
      }
    },
    pageWidth() {
      if (this.pageConfig.direction == "1") {
        return this._pageWidth;
      } else {
        return this._pageHeight;
      }
    },
    _pageHeight() {
      return getPageHeight({
        pageType: this.pageConfig.pageType,
        height: this.pageConfig.pageHeight,
      });
    },
    _pageWidth() {
      return getPageWidth({
        pageType: this.pageConfig.pageType,
        width: this.pageConfig.pageWidth,
      });
    },

    backgroundImage() {
      return this.pageConfig.isBgImg == "1" && this.pageConfig.bgImg
        ? `${this.apiUrl}system/annexesfile/${this.pageConfig.bgImg}?token=${this.token}`
        : "";
    },
    backgroundRepeat() {
      return this.pageConfig.bgRepeat == "2" //"自适应铺满"
        ? ""
        : this.pageConfig.bgRepeat == "3" //水平重复
        ? "repeat-x"
        : "no-repeat";
    },
    border() {
      return this.pageConfig.borderShow != "1"
        ? ""
        : `${this.pageConfig.borderSize}pt ${this.pageConfig.borderLine} ${this.pageConfig.borderColor}`;
    },
  },
  methods: {
    async handleClick() {
      if(this.loading){
        return;
      }
      if (this.code && this.schemaCode != this.code) {
        this.loading = true;
        const api = window.$api.print.printTemplate;
        const data = await this.$awaitWraper(api.getByCode(this.code));
        this.pageSchema = JSON.parse(data.lrPrintTemplateEntity.f_Component);
        this.schemaCode = this.code;
        this.loading = false;
      }

      this.lr_loadUsers(this.loginInfo.f_UserId);
      this.timeNum = 1200;
      setTimeout(async () => {
        await this._print();
      }, 60);
    },
    async _print() {
      if (this.myPageSchema) {
        if (this.$store.state.app.axiosLoadingNum == 0 || this.timeNum == 0) {
          const { headers, pages } = await this.getPagesJson();
          const html = await this.getIframeHtml(headers, pages);
          if (html) {
            this.print(html);
          }
          this.$emit("click");
        } else {
          this.timeNum--;
          setTimeout(async () => {
            await this._print();
          }, 100);
        }
      }
    },

    print(html) {
      // 打印表单
      this.write(html);
      setTimeout(() => {
        this.getIframe().window.print();
      });
    },
    async getPagesJson() {
      const headers = [];
      // 格式化组件数据
      const formData = await this.getMyFormData();
      const pages = this.$deepClone(this.myPageSchema.pages);

      for (let page of pages) {
        const followComponents = {};
        const tables = page.components.filter(
          (t) => t.componentType == "table"
        );
        for (let table of tables) {
          if (table.components) {
            const _followComponents = table.components.split(",");
            if (_followComponents.length > 0) {
              for (let _followComponentId of _followComponents) {
                followComponents[_followComponentId] = true;
              }
            }
          }
        }

        const components = [];
        for (let config of page.components) {
          if (!config._isAdd) {
            config._page = 0;
            config._top = config.top + this.pageConfig.paddingTop;
          }
          if (config.componentType != "table") {
            config._height = config.height;
            config._bottom = config.top + config.height;
            config._data = formData[config.table];
          }

          config._left = config.left + this.pageConfig.paddingLeft;
          config._width = config.width;
          config._apiUrl = this.apiUrl;
          config._token = this.token;

          if (this.pageConfig.isHeaderShow == "1" && config.isHeader) {
            // 如果是页眉
            headers.push(config);
          } else if (!followComponents[config.id]) {
            config._isAdd = true;
            components.push(config);
          }

          if (config.componentType == "table" && !followComponents[config.id]) {
            config._bottom = config.top + config.thHeight + config.rowHeight;
            config._isth = true;
            this.formatComponent(config, formData, components, page.components);
          }
        }
        page.components = components;
      }

      const pagesJson = [];
      let pageNum = 0;
      for (let page of pages) {
        const _pagesJson = [];

        for (let config of page.components) {
          _pagesJson[config._page] = _pagesJson[config._page] || [];
          _pagesJson[config._page].push(config);
        }

        for (let _pageJsonItem of _pagesJson) {
          const pageItem = {
            pageNum: 0,
            components: _pageJsonItem,
          };
          if (pageNum + 1 >= this.pageConfig.footerStart) {
            if (pagesJson.length == 0) {
              pageItem.pageNum = 1;
            } else {
              pageItem.pageNum = pagesJson[pagesJson.length - 1].pageNum + 1;
            }
          }
          pagesJson.push(pageItem);
        }
        pageNum++;
      }

      return {
        headers,
        pages: pagesJson,
      };
    },
    formatComponent(config, formData, components, pageComponents, pre) {
      let top = config._top;
      if (pre) {
        top = pre._top + pre._height + config.top - pre._bottom;
        config._page = pre._page;
        config._pre = pre;
      }

      let height = 0;
      if (config.componentType == "table") {
        const data = formData[config.table] || [];

        if (data.length > 0 && data[0]._learun_row_height == undefined) {
          // 获取表格行高
          config._data = data;
          const configComponent = this.myComponentList[config.componentType];
          const configHtml = configComponent.getHtml(config, this.isPreview);
          const pageHtml = this.getHtml(this.getPageHtml2(configHtml, ""));

          const  iframe = document.createElement('iframe');
          document.body.appendChild(iframe);
          this.write(pageHtml,iframe);
          const rows = this.getIframeDoc(iframe).getElementsByTagName("tr");
          for (let i = 0; i < rows.length; i++) {
            if(i > 0){
              let row = rows[i];
              data[i-1]._learun_row_height = this.$toPt(row.clientHeight);
            }
          }
          iframe.remove();
        }

        if (
          config._isth &&
          top + config.thHeight >
            this.pageHeightPt - this.pageConfig.paddingBottom
        ) {
          // 表格需要换页
          top = this.pageConfig.paddingTop;
          config._page++;
        }

        let isBreakTable = false;
        let _contentHeight =
          this.pageHeightPt - this.pageConfig.paddingBottom - top;
        if (config._isth) {
          _contentHeight -= config.thHeight;
        }

        const  {rowNum,tableHeight} =this.getTableRowsNum(data,_contentHeight)// _contentHeight / config.rowHeight;
        height = tableHeight;
        if (rowNum >= data.length) {
          config._data = data;
        } else {
          // 需要换页;
          config._data = data.splice(0, rowNum);
          isBreakTable = true;
        }

        if (config._isth) {
          height += config.thHeight;
        }

        config._top = top;
        config._height = height;
        if (!config._isAdd) {
          config._isAdd = true;
          components.push(config);
        }

        if (isBreakTable) {
          const newConfig = this.$deepClone(config);
          newConfig._top = this.pageConfig.paddingTop;
          newConfig._page++;
          newConfig._isth = false; // 表格分页，分页部分不加表头
          newConfig._isAdd = false;
          this.formatComponent(
            newConfig,
            formData,
            components,
            pageComponents,
            null
          );
        } else {
          // 判断是否有关联组件
          if (config.components) {
            const _followComponents = config.components.split(",");
            if (_followComponents.length > 0) {
              for (let _followComponentId of _followComponents) {
                const followComponent = pageComponents.find(
                  (t) => t.id == _followComponentId
                );
                if (followComponent) {
                  if (followComponent.componentType == "table") {
                    followComponent._bottom =
                      followComponent.top +
                      followComponent.thHeight +
                      followComponent.rowHeight;
                    followComponent._isth = true;
                  }

                  this.formatComponent(
                    followComponent,
                    formData,
                    components,
                    pageComponents,
                    config
                  );
                }
              }
            }
          }
        }
      } else {
        if (
          config._top + config._height >
          this.pageHeightPt - this.pageConfig.paddingBottom
        ) {
          config._top = this.pageConfig.paddingTop;
          config._page++;
        } else {
          config._top = top;
        }
        if (!config._isAdd) {
          config._isAdd = true;
          components.push(config);
        }
      }
    },

    async getIframeHtml(headers, pages) {
      let html = "";
      for (let page of pages) {
        if (html != "") {
          html += `<div style="page-break-after:always;"></div>`;
        }
        html += await this.getPageHtml(
          headers,
          page,
          pages[pages.length - 1].pageNum
        );
      }
      return this.getHtml(html);
    },

    getHtml(html) {
      const res = `<!DOCTYPE html>
      <html xmlns="http://www.w3.org/1999/xhtml">
        <head>
        <meta charset="UTF-8">
        <title></title>
        <meta name="Generator" content="力">
          <style media="print">
            @page { border:0;size:${this.pageWidth}mm ${
        this.pageHeight
      }mm;margin:0 !important;padding:0 !important;}
            @media print {
              div {
                box-sizing: border-box;
              }
              .page-panel{
                position: relative;
                width: ${this.pageWidth}mm;
                height: ${
                  this.pageHeight == 297
                    ? this.pageHeight - 1
                    : this.pageHeight - 1
                }mm;
                overflow: hidden;
                border:${this.border};
              }
              .page-line {page-break-after: always;}
              .page-background{
                position: absolute;
                width:100%;
                height: 100%;
                left: 0;
                top: 0;
                z-index: -1;

              }
              .page-footer {
                position: absolute;
                left: 0;
                width: 100%;
              }
              .page-item{
                position: absolute;
                overflow: hidden;
              }
              body {
                -webkit-print-color-adjust: exact;
                print-color-adjust: exact;
                color-adjust: exact;
                padding:0;
                margin:0;
              }
            }
          </style>
        </head>
        <body>${html}</body>
      </html>`;
      return res;
    },

    async getPageHtml(headers, page, pageTotals) {
      //打印组件
      let bodyhtml = "";

      if (page.pageNum > 0) {
        for (let item of headers) {
          const component = this.myComponentList[item.componentType];
          if (item.display && component && component.getHtml) {
            bodyhtml += await component.getHtml(item, this.isPreview);
          }
        }
      }

      for (let item of page.components) {
        const component = this.myComponentList[item.componentType];
        if (item.display && component && component.getHtml) {
          bodyhtml += await component.getHtml(item, this.isPreview);
        }
      }

      let footerHtml = "";
      if (this.pageConfig.isFooterShow == "1" && page.pageNum > 0) {
        footerHtml = `
        <div class="page-footer"
          style="
          bottom:${this.pageConfig.footerBottomSize}pt;
          text-align:${this.pageConfig.footerAlign}
          "
        >
          ${pageNumText(this.pageConfig.footerStyle, page.pageNum, pageTotals)}
        </div>`;
      }

      let bgImg = await this.getImg(this.backgroundImage);

      return this.getPageHtml2(bodyhtml, footerHtml, bgImg);
    },
    getPageHtml2(bodyhtml, footerHtml, bgImg) {
      const pageHtml = `
      <div
        original-height="${this.pageHeight}"
        class="page-panel"
      >

        <div class="page-background"
          style="
            background-color:${
              this.pageConfig.isBgColor != "1"
                ? "#fff"
                : this.pageConfig.bgColor
            };
            opacity: ${this.pageConfig.bgOpacity * 0.01};
            background-image:url(${bgImg});
            background-size:${this.pageConfig.bgImgW}pt ${
        this.pageConfig.bgImgH
      }pt;
            background-repeat:${this.backgroundRepeat};
            background-position:${this.pageConfig.originL}pt ${
        this.pageConfig.originT
      }pt;
          "
        >
        </div>
        ${bodyhtml}
        ${footerHtml}
      </div>`;
      return pageHtml;
    },

    async getMyFormData() {
      if (this.getFormData) {
        const res = this.$deepClone(await this.getFormData());
        return res;
      } else {
        return {};
      }
    },

    getIframe(iframe) {
      if(!iframe){
        iframe = this.$refs.iframe;
      }
      return iframe.contentWindow ? iframe.contentWindow : iframe;
    },
    getIframeDoc(iframe) {
      if(!iframe){
        iframe = this.$refs.iframe;
      }
      iframe = this.getIframe(iframe);
      return iframe.document
        ? iframe.document
        : iframe.contentDocument;
    },
    write(html,iframe) {
      const doc = this.getIframeDoc(iframe);
      doc.open();
      doc.write(html);
      doc.close();
    },

    getImg(backgroundImage) {
      return new Promise((resolve) => {
        let imgObj = new Image();
        imgObj.src = backgroundImage;
        imgObj.onload = () => {
          resolve(backgroundImage);
        };
        imgObj.onerror = () => {
          resolve(backgroundImage);
        };
      });
    },

    getTableRowsNum(data,contentHeight){
      let height = 0;
      let rowNum = data.length;
      let tableHeight = 0;
      for(let i= 0;i<data.length;i++){
        height += data[i]._learun_row_height;
        if(height > contentHeight){
          rowNum = i;
          break;
        }
        tableHeight = height;

      }
      return {rowNum,tableHeight};
    }
  },
};
</script>

<style></style>
